package com.zhangmeng.tools.controller;

import cn.hutool.core.io.FileUtil;
import com.zhangmeng.tools.server.SimpleServer;
import com.zhangmeng.tools.utils.AlertUtils;
import com.zhangmeng.tools.utils.ImagePath;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.nio.charset.StandardCharsets;

/**
 * @author : 芊芊墨客
 * @version : 1.0
 * @date : 2023-03-10 11:35
 */
@Slf4j
public class HttpServerController {

    public enum ContentType {
        /**
         * Rest请求JSON编码
         */
        JSON("application/json");

        private  String value;

        ContentType(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    @FXML
    public TextField server_port;

    @FXML
    public TextField file_dir_root;

    @FXML
    public ComboBox<ContentType> data_combox;

    @FXML
    public TextField server_api;

    @FXML
    public Button add_api;

    @FXML
    public Button server;

    @FXML
    public Button stop_server;

    @FXML
    public RadioButton common_api;

    @FXML
    public RadioButton file_api;

    @FXML
    public RadioButton res_json;

    @FXML
    public RadioButton custom_res;

    @FXML
    public ListView<Data> api_list;

    @FXML
    public TextField custom_res_content;

    @FXML
    public Button choose_json_button;

    @FXML
    public TextField json_file_path;

    private SimpleServer simpleServer = null;

    private static final int default_port = 8083;

    private final ObservableList<ContentType> data_type_list = FXCollections.observableArrayList();
    private final ObservableList<Data> api_data_list = FXCollections.observableArrayList();
    private final SimpleObjectProperty<RadioButton> choose_but = new SimpleObjectProperty<>();
    private final SimpleObjectProperty<RadioButton> choose_res = new SimpleObjectProperty<>();
    private final SimpleObjectProperty<File> choose_file = new SimpleObjectProperty<>();
    private final SimpleObjectProperty<ContentType> choose_content_type = new SimpleObjectProperty<>();

    @FXML
    public void initialize() {

        choose_json_button.setText(null);
        ImageView iv = new ImageView(new Image(ImagePath.path(ImagePath.ImagePathType.IMAGE_FILE)));
        iv.setPreserveRatio(true);
        iv.setFitWidth(18);
        choose_json_button.setGraphic(iv);
        choose_json_button.setOnAction(event -> {
            Stage stage = new Stage();
            FileChooser fc = new FileChooser();
            fc.setTitle("单选文件");
            fc.getExtensionFilters().addAll(
                    new FileChooser.ExtensionFilter("文本类型", "*.json")
            );

            File file = fc.showOpenDialog(stage);

            if (file == null) {
                return;
            }
            json_file_path.setText(file.getPath());
            choose_file.set(file);
        });

        //返回数据类型
        data_type_list.addAll(ContentType.values());
        data_combox.setItems(data_type_list);
        data_combox.getSelectionModel().select(ContentType.JSON);
        choose_content_type.set(ContentType.JSON);
        data_combox.setCellFactory(new Callback<>() {
            @Override
            public ListCell<ContentType> call(ListView<ContentType> param) {
                return new ListCell<>() {
                    @Override
                    protected void updateItem(ContentType data, boolean b) {
                        super.updateItem(data, b);
                        if (!b) {
                            HBox hBox = new HBox();
                            hBox.setAlignment(Pos.CENTER);
                            hBox.getChildren().add(new Label(data.getValue()));
                            this.setGraphic(hBox);
                        }
                    }
                };
            }
        });

        data_combox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                log.info("ContentType:---{}", newValue);
                choose_content_type.setValue(newValue);
            }
        });

        api_list.setItems(api_data_list);
        api_list.setFixedCellSize(40);
        api_list.setCellFactory(new Callback<>() {
            @Override
            public ListCell<Data> call(ListView<Data> param) {
                return new ListCell<>() {
                    @Override
                    protected void updateItem(Data data, boolean b) {
                        super.updateItem(data, b);
                        if (!b) {
                            HBox hBox = new HBox();
                            hBox.setAlignment(Pos.CENTER);
                            if (data.is_json_file) {
                                hBox.getChildren().add(new Label("==>接口地址:" + data.getApi() + "==>返回类型:json"  + "==>是否是文件接口:" + data.isIs_file_api() + "==>是否是json文件:" + data.isIs_json_file() + "==>json文件地址:" + data.file.getPath()));
                            }else {
                                hBox.getChildren().add(new Label("==>接口地址:" + data.getApi() + "==>返回类型:json"  + "==>是否是文件接口:" + data.isIs_file_api() + "==>是否是json文件:" + data.isIs_json_file()));
                            }
                            this.setGraphic(hBox);
                        }
                    }
                };
            }
        });

        ToggleGroup tg = new ToggleGroup();
        common_api.setToggleGroup(tg);
        file_api.setToggleGroup(tg);
        tg.selectToggle(common_api);//默认选项
        choose_but.setValue(common_api);

        ToggleGroup tg2 = new ToggleGroup();
        res_json.setToggleGroup(tg2);
        custom_res.setToggleGroup(tg2);
        tg2.selectToggle(custom_res);//默认选项
        choose_res.setValue(custom_res);

        tg.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
            RadioButton radioButton = (RadioButton) newValue;
            choose_but.setValue(radioButton);
        });

        tg2.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
            RadioButton radioButton = (RadioButton) newValue;
            choose_res.setValue(radioButton);
        });

        add_api.setOnAction(event -> {

            if (server_api.getText().length() == 0 ){
                AlertUtils.alert_warning("添加的api不能为空!");
                return;
            }

            if (data_combox.getSelectionModel().getSelectedItem() == null){
                AlertUtils.alert_warning("请api返回数据类型!");
                return;
            }

            Data data = new Data();
            data.setApi(server_api.getText());
            RadioButton value1 = choose_but.getValue();
            data.setIs_file_api(!value1.getId().equals(common_api.getId()));

            RadioButton value = choose_res.getValue();
            if (value.getId().equals(custom_res.getId())){
                if (custom_res_content.getText().length() == 0 ){
                    AlertUtils.alert_warning("自定义返回内容不能为空!");
                    return;
                }
                data.setContent(custom_res_content.getText());
                data.setIs_json_file(false);
            }else {
                File file = choose_file.getValue();
                if (file == null){
                    AlertUtils.alert_warning("请选择返回的json文件!");
                    return;
                }
                data.setFile(file);
                data.setIs_json_file(true);
            }
            api_data_list.add(data);
        });

        if (server_port.getText().length() == 0) {
            server_port.setText(String.valueOf(HttpServerController.default_port));
        }

        server.setOnAction(event -> {

            if (server_port.getText().length() == 0) {
                AlertUtils.alert_warning("请输入服务端口再试!");
                return;
            }

            simpleServer = new SimpleServer(Integer.parseInt(server_port.getText()));

            if (file_dir_root.getText().length() > 0) {
                simpleServer.setRoot(file_dir_root.getText());
            }

            for (Data item : api_list.getItems()) {
                if (item.isIs_file_api()){//文件api

                }else {
                    String content = null;
                    if (item.isIs_json_file()){
                        File file = item.getFile();
                        content = FileUtil.readString(file,StandardCharsets.UTF_8);
                    }else {
                        content = item.getContent();
                    }
                    String finalContent = content;
                    simpleServer.addAction(item.getApi(),(request, response) -> {
                        response.write(finalContent, "application/json;charset=utf-8");
                    });
                }
            }

            //启动服务器
            simpleServer.start();
            AlertUtils.alert_msg("服务启动成功!");
        });

        stop_server.setOnAction(event -> {
            simpleServer.stop();
            AlertUtils.alert_msg("服务关闭成功!");
        });
    }


    public static class Data {

        private String api;

        private File file;

        private String content;

        private boolean is_json_file;

        private boolean is_file_api;

        public boolean isIs_file_api() {
            return is_file_api;
        }

        public void setIs_file_api(boolean is_file_api) {
            this.is_file_api = is_file_api;
        }

        public boolean isIs_json_file() {
            return is_json_file;
        }

        public void setIs_json_file(boolean is_json_file) {
            this.is_json_file = is_json_file;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public Data() {
        }

        public String getApi() {
            return api;
        }

        public void setApi(String api) {
            this.api = api;
        }

        public File getFile() {
            return file;
        }

        public void setFile(File file) {
            this.file = file;
        }

        public Data(ContentType contentType, String api, File file) {
            this.api = api;
            this.file = file;
        }
    }
}
